package cn.qyd.javamap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;

/**
 * @author 邱运铎
 * @date 2024-03-05 19:06
 */
public class HashMapDemo {
    public static void main(String[] args) {
        HashMap<Integer,Integer> hashMap = new HashMap<>();
        Integer put = hashMap.put(1, 2);
        System.out.println(put);
        put = hashMap.put(1,3);
        System.out.println(put);
        hashMap.put(2,2);
        System.out.println(hashMap.entrySet());
        Hashtable hashtable = new Hashtable();
        hashtable.put(12,12);
        System.out.println("-----compute--------");
        List<Integer> list1 = new ArrayList<>();
        list1.add(1000);
        HashMap<Integer, List<Integer>> demoMap = new HashMap<>();
        /**
         * BiFunction<T, U, R>  该函数接口代表,存在 T, U 两个入参，类型为T,U。 返回值类型 为 R
         * HashMap中computer， computerIfPresent 第二个参数都是上面这个类具体如下：
         * BiFunction<? super K, ? super V, ? extends V> , 其中K==T, V==U, V==R
         * 代表入参为hashMap的key和value类型, 返回值为value类型的值
         *
         * Function<T, R>  该函数接口代表,存在 T一个入参，类型为T。 返回值类型 为 R
         * HashMap中computerIfAbsent 第二个参数都是上面这个类具体如下：
         * Function<? super K, ? extends V> 其中K==T, V==R
         * 代表入参一个k,并和key的类型保持一致， 返回的值类型和value保持一致
         *
         * compute系列方法都是一个获取key对应的值方法，本质是get操作的含义
         */
        /**
         * compute lambda 入参是 （k, v）; 返回值是value
         * 1. key 不存在时：将key 和 lambda表达式的值作为value，插入map
         * 2. key 存在时： 将value进行lambda表达式更新，计算结果为新值
         *  key 存不存在返回值都是lambda计算后的新值
         */

        List<Integer> compute = demoMap.compute(2, (k, v) -> new ArrayList<>(list1));
        System.out.println(compute);
        System.out.println(demoMap.get(2));
        demoMap.put(3, new ArrayList() { {add(2);}});
        demoMap.compute(3, (k, v) -> v);
        System.out.println(demoMap.get(3));
        List<Integer> compute1 = demoMap.compute(3, (k, v) -> list1);
        System.out.println(compute1);
        System.out.println(demoMap.get(3));

        /**
         * computeIfPresent lambda 入参是（k, v）; 返回值是value
         * 1. key 不存在时：不做操作
         * 2. key 存在时： 将value进行lambda表达式更新，计算结果为新值
         */
        System.out.println("------computeIfPresent-------");
        // map中key不存在的情况
        List<Integer> list = demoMap.computeIfPresent(4, (v, k) -> k);
        System.out.println(list);  // 返回null
        System.out.println(demoMap.get(4)); // 返回null  表示key不存在不做操作
        // map中key存在的情况
        List<Integer> lis1 = demoMap.computeIfPresent(2, (v, k) -> k);
        System.out.println(list1);  // 返回 value的值

        /**
         * computeIfAbsent lambda 入参是k; 返回值是value类型的值
         * 1. key 不存在时：将key, 和 lambda计算后的值作为键值对插入map
         * 2. key 存在时： 不做任何操作
         */
        System.out.println("------computeIfAbsent-------");
        // key不存在时
        List<Integer> list2 = demoMap.computeIfAbsent(9, k -> lis1);
        System.out.println(demoMap.get(9));
        // key 存在时
        demoMap.put(11, new ArrayList(){{add(111);}});
        List<Integer> list3 = demoMap.computeIfAbsent(11, k -> lis1);
        System.out.println(list3);  // 返回 111， key在存在时，computeIfAbsent操作返回key对应的value,
        System.out.println(demoMap.get(11));  // 返回 111， 代表value没有变为 list1 {1000}


        /**
         * putIfAbsent
         * 1. key 不存在时：将key, 和 lambda计算后的值作为键值对插入map
         * 2. key 存在时： 不做任何操作
         */
        System.out.println("------computeIfAbsent-------");
        demoMap.put(77, new ArrayList(){{add(171717);}});
        // key 不存在时  插入成功
        demoMap.putIfAbsent(7, new ArrayList(){{add(777);}});
        System.out.println(demoMap);
        // key存在时 不做操作，下面键为77 的value仍未 171717 。而没有变为 list1 {1000}
        demoMap.putIfAbsent(77, lis1);
        System.out.println(demoMap);
    }
}
